home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Frameworks
/
Sprocket Framework DR2
/
Sprocket Starter
/
SprocketStarter Code
/
FuturesDemo.c
< prev
next >
Wrap
Text File
|
1996-06-15
|
7KB
|
252 lines
/*
File: FuturesDemo.cp
Project: Sample code for Sprocket Framework 1.1 (DR2), released 6/15/96
Contains: A demo of AE Futures functionality
To Do: ?
Sprocket Major Contributors:
----------------------------
Dave Falkenburg, producer of Sprocket 1.0
Bill Hayden, producer of Sprocket 1.1
Steve Sisak, producer of the upcoming Sprocket 2.0
Pete Alexander Steve Falkenburg Randy Thelen
Eric Berdahl Nitin Ganatra Chris K. Thomas
Marshall Clow Dave Hershey Leonard Rosenthal
Tim Craycroft Dave Mark Dean Yu
David denBoer Gary Powell
Cameron Esfahani Jon Summers Apple Computer, Inc.
Comments, Additions, or Corrections:
------------------------------------
Bill Hayden, Nikol Software <nikol@codewell.com>
*/
#include "FuturesDemo.h"
#include "AEFutures.h"
#include "AEThreads.h"
#include <Threads.h>
#include <PPCToolBox.h>
#include <EPPC.h>
#include <AppleEvents.h>
#include "UString.h"
AEDesc gNullDesc; // A null descriptor record
AEAddressDesc gSelfAddress; // A self-addressed address descriptor record
ProcessSerialNumber gSelfPSN; // This application's psn
#pragma segment handlers
pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
{
char* stringPtr;
char stringBuffer[100];
long actualSize;
DescType actualType;
OSErr theErr;
EventRecord evt;
// Beep to indicate that the question was received
while (EventAvail(everyEvent, &evt))
{
YieldToAnyThread();
}
SysBeep(1);
// Extract a string from the question.
theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
// Load a string into the answer.
stringPtr = "I’m just fine.";
theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, clen(stringPtr));
return(noErr);
}
pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
{
OSErr theErr;
TargetID theTargetID;
PortInfoRec thePortInfo;
AEAddressDesc theAddressDesc;
AppleEvent question;
AppleEvent answer;
char* stringPtr;
char stringBuffer[100];
long actualSize;
DescType actualType;
long i;
// Get the target address of the other process
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
// Start the thread that pings
for (i=0; i<30; i++)
{
YieldToAnyThread();
// Build an AppleEvent question that is addressed to the user selected target
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
// Load a string into the question.
stringPtr = "Hello server, how are you doing?";
theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, clen(stringPtr));
// Ask the question
theErr = AskForFuture(&question, &answer);
// If the answer is not a future so soon after ask, something is probably wrong.
// if (!IsFuture(&answer)) Debugger();
// Extract a string from the answer. This will cause the thread to block until the answer is received.
theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
// If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
// if (IsFuture(&answer)) Debugger();
// Dispose of the answer and the question.
theErr = AEDisposeDesc(&answer);
theErr = AEDisposeDesc(&question);
}
// Dispose of the address descriptor now that the thread no longer needs it.
theErr = AEDisposeDesc(&theAddressDesc);
return theErr;
}
pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
{
OSErr theErr;
TargetID theTargetID;
PortInfoRec thePortInfo;
AEAddressDesc theAddressDesc;
AEAddressDesc theAddressDesc2;
AppleEvent question;
AppleEvent question2;
AppleEvent answer;
AppleEvent answer2;
long i;
// Get the target addresses of the two processes
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
// Start the thread that pings
for (i=0; i<30; i++)
{
YieldToAnyThread();
// Build the questions.
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
// Ask the questions.
theErr = AskForFuture(&question, &answer);
theErr = AskForFuture(&question2, &answer2);
// Block until the answers become real.
BlockUntilReal(&answer);
BlockUntilReal(&answer2);
// Dispose of the answers and the questions.
theErr = AEDisposeDesc(&answer);
theErr = AEDisposeDesc(&answer2);
theErr = AEDisposeDesc(&question);
theErr = AEDisposeDesc(&question2);
}
// Dispose of the address descriptor now that the thread no longer needs it.
theErr = AEDisposeDesc(&theAddressDesc);
theErr = AEDisposeDesc(&theAddressDesc2);
return noErr;
}
#pragma segment Main
void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
{
AppleEvent myAppleEvent, reply;
// Create the Apple Event.
AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
// Send the Apple Event.
AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
kAEDefaultTimeout, nil, nil);
AEDisposeDesc(&myAppleEvent); // Dispose of the Apple Event.
}
pascal void InitFuturesDemo(void)
{
gSelfPSN.highLongOfPSN = 0;
gSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
gNullDesc.descriptorType = typeNull; // Initialize the global null descriptor record.
gNullDesc.dataHandle = nil;
// Initialize the futures package
InitFutures();
// Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
#if 0
AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
#else
AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
#endif
AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, NewAEEventHandlerProc(HandlePing1), 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, NewAEEventHandlerProc(HandlePing2), 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
}
pascal void CleanupFuturesDemo(void)
{
AEDisposeDesc(&gSelfAddress); // Dispose of my self-addressed descriptor.
}